package com.infra.server.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infra.server.api.Result;
import com.infra.server.entity.SysResource;
import com.infra.server.service.GetwayService;
import com.infra.server.service.SysResourceService;
import com.infra.server.utils.ConstantUtil;
import com.infra.server.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author win
 * @date 2020/12/21 11:09
 */
@RestController
@Api(value = "SysResourceController",tags = "资源相关接口")
@RequestMapping("/resource")
public class SysResourceController {

    @Resource
    private SysResourceService sysResourceService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private GetwayService getwayService;

    @ApiOperation(value = "获取资源,即接口-角色权限",notes = "1")
    @GetMapping("/list")
    public Result getResource(@RequestParam(required = false) String content,
                              @RequestParam(required = false) Integer current,
                              @RequestParam(required = false) Integer size,
                              @RequestParam(required = false) List<Integer> resourceType) {
        Map<String,Object> map = new HashMap<>();
        LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<SysResource>()
                .in(resourceType!=null,SysResource::getResourceType,resourceType)
                .like(StrUtil.isNotEmpty(content),SysResource::getName,content)
                .or()
                .like(StrUtil.isNotEmpty(content),SysResource::getDescription,content)
                .or()
                .like(StrUtil.isNotEmpty(content),SysResource::getOwner,content);
        if (current != null && size != null) {
            // 分页查询
            Page<SysResource> page = new Page<>(current,size);
            IPage<SysResource> page1 = sysResourceService.page(page,queryWrapper);
            map.put("page",page1);
        } else {
            // 获取所有资源
            List<SysResource> list = sysResourceService.list(queryWrapper);
            map.put("list",list);
        }
        return Result.ok().data(map).message("获取资源成功");
    }

    @ApiOperation(value = "添加或修改资源",notes = "1")
    @PostMapping("/save")
    public Result saveResource(@RequestBody SysResource sysResource) {
        // 添加
        if (StrUtil.hasEmpty(Convert.toStr(sysResource.getId()))) {
            QueryWrapper<SysResource> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name",sysResource.getName());
            SysResource sysResource1 = sysResourceService.getOne(queryWrapper);
            if (ObjectUtil.isNotNull(sysResource1)) {
                return Result.error().message("该资源已存在！请重命名！");
            } else {
                boolean a = sysResourceService.save(sysResource);
                if (a) {
                    if (sysResource.getResourceType() != 0) {
                        // 保存到redis
                        redisUtil.hset(ConstantUtil.RESOURCE_ROLES_MAP, sysResource.getName(),ObjectUtil.isNotEmpty(sysResource.getOwner()) ? sysResource.getOwner().split(",") : "");
                    } else {
                        redisUtil.hdel(ConstantUtil.RESOURCE_ROLES_MAP,sysResource.getName());
                    }
                    return Result.ok().message("添加资源成功");
                } else {
                    return Result.error().message("添加资源失败，请重试！");
                }
            }
        } else {
            // 修改
            boolean a = sysResourceService.updateById(sysResource);
            if (a) {
                if (sysResource.getResourceType() != 0) {
                    // 保存到redis,已存在则会覆盖
                    redisUtil.hset(ConstantUtil.RESOURCE_ROLES_MAP, sysResource.getName(),ObjectUtil.isNotEmpty(sysResource.getOwner()) ? sysResource.getOwner().split(",") : "");
                } else {
                    redisUtil.hdel(ConstantUtil.RESOURCE_ROLES_MAP,sysResource.getName());
                }
                return Result.ok().message("修改资源成功");
            } else {
                return Result.error().message("修改资源失败，请重试！");
            }
        }

    }

    @ApiOperation(value = "根据id删除资源",notes = "1")
    @GetMapping("/delete")
    public Result deleteResource(@RequestParam List<Integer> id,@RequestParam String name) {
        boolean a = sysResourceService.removeByIds(id);
        if (a) {
            // 删除redis上的资源
            redisUtil.hdel(ConstantUtil.RESOURCE_ROLES_MAP, name.split(","));
            return Result.ok().message("删除资源成功");
        } else {
            return Result.error().message("删除资源失败，请重试！");
        }
    }

    @ApiOperation(value = "从swagger获取所有接口添加进表",notes = "1")
    @GetMapping("/add_resource")
    public Result addResource() {
        JSONArray apiList = getwayService.getApiList();
        if (ObjectUtil.isNotEmpty(apiList)) {
            List<SysResource> sysResourceList = JSONArray.parseArray(JSONArray.toJSONString(apiList),SysResource.class);
            boolean a = sysResourceService.addResource(sysResourceList);
            this.initData();
            if (a) {
                return Result.ok().message("更新成功");
            }
        }
        return Result.error().message("操作失败，请检查");
    }

    @PostConstruct
    public void initData() {
        Map<String, Object> resourceRolesMap = new HashMap<>();
        // 从数据库查询需要做权限资源并存到redis
        List<SysResource> list =  sysResourceService.list(new LambdaQueryWrapper<SysResource>()
                .ne(SysResource::getResourceType,0)
                .isNotNull(SysResource::getName)
        );
        if (ObjectUtil.isNotEmpty(list)) {
            for (SysResource s : list) {
                resourceRolesMap.put(s.getName(),ObjectUtil.isNotEmpty(s.getOwner()) ? s.getOwner().split(",") : "");
            }
            redisUtil.hmset(ConstantUtil.RESOURCE_ROLES_MAP, resourceRolesMap);
        }
    }

}
